/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.amse.grigory.dchess.rules;

import org.amse.grigory.dchess.kernel.*;
import java.util.*;

/**
 *
 * @author grigory
 */
public abstract class Rules {

    public final static int COLOR_WHITE = 1;
    public final static int COLOR_BLACK = -1;
    public final static int BLACK_WIN = 1;
    public final static int WHITE_WIN = 2;
    public final static int NOBODY_WIN = 0;
    public final static int DRAW = 3;    // Fields
    protected int myHeight,  myWidth;
    protected String myName;
    protected ArrayList<Figure> myWhite,  myBlack;
    protected HashMap<String,Figure> myFigures;
    protected ArrayList<Integer> myIllegalX,  myIllegalY;

    public Rules() {
        myName = "";
        myWhite = new ArrayList<Figure>();
        myBlack = new ArrayList<Figure>();
        myIllegalX = new ArrayList<Integer>();
        myIllegalY = new ArrayList<Integer>();
    }

    // Getters
    public void setFigures(HashMap< String,Figure> figures) {
        myFigures = figures;
    }

    public int getHeight() {
        return myHeight;
    }

    public int getWidth() {
        return myWidth;
    }

    public String getName() {
        return myName;
    }

    public int getWhiteNumber() {
        return myWhite.size();
    }

    public int getBlackNumber() {
        return myBlack.size();
    }

    public int getIllegalSquareNumber() {
        return myIllegalX.size();
    }

    public int getIllegalX(int index) {
        return myIllegalX.get(index);
    }

    public int getIllegalY(int index) {
        return myIllegalY.get(index);
    }

    // Return copy of black figure
    public Figure getBlack(int index) {
        return myBlack.get(index).clone();
    }

    // Return copy of white figure
    public Figure getWhite(int index) {
        return myWhite.get(index).clone();
    }
    // Setters

    public void setHeight(int height) {
        myHeight = height;
    }

    public void setWidth(int width) {
        myWidth = width;
    }

    public void setName(String name) {
        myName = name;
    }

    public void setIllegalX(int index, int x) {
        myIllegalX.set(index, x);
    }

    public void setIllegalY(int index, int y) {
        myIllegalX.set(index, y);
    }

    // Methods
    public void addIllegalSquare(int x, int y) {
        myIllegalX.add(x);
        myIllegalY.add(y);
    }

    public boolean addWhite(Figure figure) {
        Figure f = figure.clone();
        int length = myIllegalX.size();
        int x = f.getX();
        int y = f.getY();
        if ((x < 1) || (x > myWidth) || (y < 1) || (y > myHeight)) {
            return false;
        }
        for (int i = 0; i < length; ++i) {
            if ((myIllegalX.get(i) == x - 1) && (myIllegalY.get(i) == y - 1)) {
                return false;
            }
        }
        f.setColor(0);
        myWhite.add(f);
        return true;
    }

    public boolean addBlack(Figure figure) {
        Figure f = figure.clone();
        int length = myIllegalX.size();
        int x = f.getX();
        int y = f.getY();
        if ((x < 1) || (x > myWidth) || (y < 1) || (y > myHeight)) {
            return false;
        }
        for (int i = 0; i < length; ++i) {
            if ((myIllegalX.get(i) == x - 1) && (myIllegalY.get(i) == y - 1)) {
                return false;
            }
        }
        length = f.getMovesCount();
        for (int i = 0; i < length; ++i) {
            f.setMoveY(i, -f.getMoveY(i));
        }
        length = f.getEatCount();
        for (int i = 0; i < length; ++i) {
            f.setEatY(i, -f.getEatY(i));
        }
        f.addTransform(myHeight + 1 - f.getTransformLine(), f.getTransformName());       
        f.setColor(1);
        myBlack.add(f);
        return true;
    }

    public void deleteWhite(int index) {
        myWhite.remove(index);
    }

    public void deleteBlack(int index) {
        myBlack.remove(index);
    }

    public void deleteIllegalSquare(int index) {
        myIllegalX.remove(index);
        myIllegalY.remove(index);
    }

    // Abstract Methods
    public abstract int isWin(Square[][] board, int color);

    public abstract Rules clone();

    public abstract boolean canMove(Square[][] board, int x, int y, int tx, int ty, int color);

    public abstract boolean makeMove(Square[][] board, int x, int y, int tx, int ty, int color, Desk desk);

    public abstract boolean makeSMove(Square[][] board, int x, int y, int tx, int ty, int color);

    public abstract boolean start(Square[][] board);

    public abstract String getMessage(Square[][] board, int color);
}
